"""
SSL证书平台自动签到系统 - 带失败重试版本
"""

import requests
import time
import json
import urllib3
from typing import Dict, List, Optional, Any

# 彻底禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class SSLSignSystem:
    """SSL证书平台自动签到核心类"""

    def __init__(self, user_id: str, config: Dict[str, Any] = None):
        self.user_id = user_id
        self.base_url = "https://lcjm.qajidian.cn/api/wechat"
        self.fixed_param = "e30%3D"

        # 配置参数
        self.config = {
            'max_ads': 10,
            'ad_wait_time': 2,
            'request_timeout': 30,
            'retry_times': 3,
            'retry_delay': 5,
            'max_sign_attempts': 10,  # 最大签到尝试次数
            'sign_retry_delay': 1,  # 签到重试延迟(秒)
        }
        if config:
            self.config.update(config)

        # 初始化会话
        self.session = requests.Session()
        self.session.trust_env = False
        self.session.proxies.clear()

        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Connection': 'keep-alive',
            'Referer': 'https://lcjm.qajidian.cn/'
        })

    def get_timestamp(self) -> str:
        """生成10位时间戳"""
        return str(int(time.time()))[-10:]

    def build_url(self, endpoint: str) -> str:
        """构建完整的URL"""
        return f"{self.base_url}/{endpoint}?d={self.fixed_param}&s={self.user_id}&_t={self.get_timestamp()}"

    def safe_request(self, method: str, url: str, **kwargs) -> requests.Response:
        """安全的请求方法"""
        for attempt in range(self.config['retry_times']):
            try:
                response = self.session.request(
                    method,
                    url,
                    timeout=self.config['request_timeout'],
                    verify=False,
                    **kwargs
                )

                if response.status_code == 200:
                    return response
                else:
                    print(
                        f" 请求失败: 状态码 {response.status_code}, 尝试 {attempt + 1}/{self.config['retry_times']}")
            except Exception as e:
                print(f" 请求异常: {e}, 尝试 {attempt + 1}/{self.config['retry_times']}")

            if attempt < self.config['retry_times'] - 1:
                time.sleep(self.config['retry_delay'])

        raise Exception(f" 请求失败: {url}, 已达到最大重试次数")

    def get_user_info(self) -> Optional[Dict[str, Any]]:
        """获取用户信息"""
        try:
            url = self.build_url("Account/show")
            print(f" 请求用户信息...")
            response = self.safe_request("GET", url)
            data = response.json()

            if data.get('info') and data['info'].get('list'):
                user_info = {'user_id': self.user_id}
                key_map = {
                    '类型': 'type',
                    '邮箱': 'email',
                    '手机': 'phone',
                    '注册': 'register_time',
                    '申请证书': 'apply_count',
                    '申请证书成功': 'success_count',
                    '手动删除证书': 'delete_count',
                    '积分数量': 'points',
                    '短信数量': 'sms_count',
                    '独立通道': 'channel_count'
                }

                for item in data['info']['list']:
                    key = key_map.get(item['n'], item['n'])
                    user_info[key] = item['v']

                print(f" 用户信息获取成功")
                return user_info
            return None
        except Exception as e:
            print(f" 获取用户信息失败: {e}")
            return None

    def check_sign_status(self) -> Dict[str, Any]:
        """检查签到状态"""
        try:
            url = self.build_url("Sign/show")
            print(f" 检查签到状态...")
            response = self.safe_request("GET", url)
            return response.json()
        except Exception as e:
            print(f" 检查签到状态失败: {e}")
            raise

    def watch_ad(self) -> Dict[str, Any]:
        """观看广告"""
        try:
            url = self.build_url("Sign/watchAd")
            print(f" 观看广告...")
            response = self.safe_request("GET", url)
            data = response.json()
            print(f" 广告响应: {json.dumps(data, ensure_ascii=False)}")
            return data
        except Exception as e:
            print(f" 观看广告失败: {e}")
            raise

    def do_sign(self) -> Dict[str, Any]:
        """执行签到"""
        try:
            url = self.build_url("Sign/sign")
            print(f" 执行签到...")
            response = self.safe_request("POST", url, headers={'Content-Type': 'application/json'})
            data = response.json()
            print(f" 签到响应: {json.dumps(data, ensure_ascii=False)}")
            return data
        except Exception as e:
            print(f" 执行签到失败: {e}")
            raise

    def parse_sign_status(self, status_data: Dict[str, Any]) -> Dict[str, Any]:
        """解析签到状态信息"""
        try:
            info = status_data['info']
            result = info['result']

            # 检查是否已经签到（根据theme判断）
            already_signed = result.get('theme') == 'success'

            # 解析aa字段
            if 'aa' in info:
                aa_parts = info['aa'].split(',')
                if len(aa_parts) >= 3:
                    wait_time = int(aa_parts[0])
                    ad_count = int(aa_parts[1])
                    can_speed = aa_parts[2] == 'canSpeed'
                else:
                    wait_time = 0
                    ad_count = 0
                    can_speed = False
            else:
                wait_time = 0
                ad_count = 0
                can_speed = info.get('canSpeed', False)

            return {
                'already_signed': already_signed,
                'can_sign': info.get('canSign', False),
                'can_speed': can_speed,
                'wait_time': wait_time,
                'ad_count': ad_count,
                'description': result.get('description', ''),
                'title': result.get('title', ''),
                'theme': result.get('theme', 'default')
            }
        except Exception as e:
            print(f" 解析签到状态失败: {e}")
            return {
                'already_signed': False,
                'can_sign': False,
                'can_speed': False,
                'wait_time': 0,
                'ad_count': 0,
                'description': '',
                'title': '',
                'theme': 'default'
            }

    def smart_speed_up(self, original_wait_time: int) -> bool:
        """智能加速：观看广告减少等待时间"""
        print("⚡ 开始智能加速...")

        # 计算需要观看的广告次数（每次广告减少约42秒）
        ads_needed = min((original_wait_time + 41) // 42, self.config['max_ads'])
        print(f" 预计需要观看 {ads_needed} 次广告来减少等待时间")

        for i in range(ads_needed):
            print(f"    观看第 {i + 1} 次广告...")
            ad_result = self.watch_ad()

            # 检查广告观看结果
            if ad_result.get('info') and ad_result['info'].get('number'):
                print(f"    第 {i + 1} 次广告观看成功")

                # 等待服务器处理
                time.sleep(self.config['ad_wait_time'])

                # 重新检查状态
                new_status_data = self.check_sign_status()
                new_status_info = self.parse_sign_status(new_status_data)

                print(f"    新状态: 等待{new_status_info['wait_time']}秒")

                # 如果可以直接签到了，返回成功
                if new_status_info['can_sign'] or new_status_info['already_signed']:
                    print(" 加速完成，可以签到了！")
                    return True

                # 如果等待时间已经很少，继续观看广告
                if new_status_info['wait_time'] <= 0:
                    print(" 等待时间已归零，可以签到了！")
                    return True

            else:
                print(" 广告观看失败，停止加速")
                break

        # 检查最终状态
        final_status_data = self.check_sign_status()
        final_status_info = self.parse_sign_status(final_status_data)

        return final_status_info['can_sign'] or final_status_info['already_signed']

    def auto_sign_with_retry(self) -> Dict[str, Any]:
        """完整的自动签到流程 - 带失败重试机制"""
        total_start_time = time.time()
        attempt_count = 0

        while attempt_count < self.config['max_sign_attempts']:
            attempt_count += 1
            print(f"\n 第 {attempt_count} 次签到尝试...")

            start_time = time.time()
            try:
                print(f" 开始自动签到流程 - 用户ID: {self.user_id}")

                # 获取用户信息
                user_info = self.get_user_info()
                if user_info:
                    print(f" 用户邮箱: {user_info.get('email', 'N/A')}")
                    print(f" 当前积分: {user_info.get('points', 'N/A')}")
                    original_points = user_info.get('points')
                else:
                    original_points = None
                    print(" 用户信息获取失败，继续尝试签到...")

                # 检查签到状态
                status_data = self.check_sign_status()
                status_info = self.parse_sign_status(status_data)

                print(f" 签到状态:")
                print(f"    主题: {status_info['theme']}")
                print(f"    标题: {status_info['title']}")
                print(f"    描述: {status_info['description']}")
                print(f"    可签到: {status_info['can_sign']}")
                print(f"    可加速: {status_info['can_speed']}")
                print(f"    等待时间: {status_info['wait_time']}秒")
                print(f"    已看广告: {status_info['ad_count']}次")
                print(f"    已签到: {status_info['already_signed']}")

                # 如果已经签到过了，直接返回成功
                if status_info['already_signed']:
                    print(" 今日已签到，无需重复签到")
                    return {
                        'success': True,
                        'message': '今日已签到，无需重复',
                        'already_signed': True,
                        'execution_time': round(time.time() - start_time, 2),
                        'total_time': round(time.time() - total_start_time, 2),
                        'attempts': attempt_count
                    }

                # 直接签到
                if status_info['can_sign']:
                    print(" 直接执行签到...")
                    sign_result = self.do_sign()

                    if sign_result.get('dialog') and '签到成功' in sign_result['dialog']['content']:
                        print(f" 签到成功! {sign_result['dialog']['content']}")

                        # 获取最新积分
                        new_user_info = self.get_user_info()
                        new_points = new_user_info.get('points') if new_user_info else None

                        points_info = ""
                        if new_points and original_points and new_points != original_points:
                            points_info = f"，积分 {original_points} → {new_points}"

                        return {
                            'success': True,
                            'message': f"{sign_result['dialog']['content']}{points_info}",
                            'points_change': int(new_points) - int(
                                original_points) if new_points and original_points else 1,
                            'execution_time': round(time.time() - start_time, 2),
                            'total_time': round(time.time() - total_start_time, 2),
                            'attempts': attempt_count
                        }
                    else:
                        print(f" 签到结果异常，准备重试...")
                        # 继续循环重试

                # 智能加速
                elif status_info['can_speed'] and status_info['wait_time'] > 0:
                    print(f" 需要等待 {status_info['wait_time']} 秒，尝试加速...")

                    # 执行智能加速
                    can_sign_now = self.smart_speed_up(status_info['wait_time'])

                    if can_sign_now:
                        print(" 加速完成，执行签到...")
                        sign_result = self.do_sign()

                        if sign_result.get('dialog') and '签到成功' in sign_result['dialog']['content']:
                            print(f" 签到成功! {sign_result['dialog']['content']}")

                            # 获取最新积分
                            new_user_info = self.get_user_info()
                            new_points = new_user_info.get('points') if new_user_info else None

                            points_info = ""
                            if new_points and original_points and new_points != original_points:
                                points_info = f"，积分 {original_points} → {new_points}"

                            return {
                                'success': True,
                                'message': f"{sign_result['dialog']['content']}{points_info}",
                                'points_change': int(new_points) - int(
                                    original_points) if new_points and original_points else 1,
                                'execution_time': round(time.time() - start_time, 2),
                                'total_time': round(time.time() - total_start_time, 2),
                                'attempts': attempt_count
                            }
                        else:
                            print(f" 签到结果异常，准备重试...")
                            # 继续循环重试
                    else:
                        # 检查最终状态
                        final_status_data = self.check_sign_status()
                        final_status_info = self.parse_sign_status(final_status_data)

                        if final_status_info['wait_time'] > 0:
                            print(f" 加速后仍需等待 {final_status_info['wait_time']} 秒，准备重试...")
                        else:
                            print(f" 加速完成但签到失败，准备重试...")
                else:
                    if status_info['wait_time'] > 0:
                        print(f" 需要等待 {status_info['wait_time']} 秒后才能签到，准备重试...")
                    else:
                        print(" 未知状态，无法签到，准备重试...")

            except Exception as e:
                print(f" 自动签到失败: {e}，准备重试...")

            # 如果当前尝试失败，等待一段时间后重试
            if attempt_count < self.config['max_sign_attempts']:
                wait_time = self.config['sign_retry_delay']
                print(f" 等待 {wait_time} 秒后重试...")
                time.sleep(wait_time)
            else:
                print(f" 已达到最大重试次数 {self.config['max_sign_attempts']}，停止重试")

        # 所有尝试都失败
        return {
            'success': False,
            'message': f'签到失败，已达到最大重试次数 {self.config["max_sign_attempts"]}',
            'execution_time': round(time.time() - total_start_time, 2),
            'total_time': round(time.time() - total_start_time, 2),
            'attempts': attempt_count
        }


def main():
    """主函数"""
    print("=" * 60)
    print(" SSL证书平台自动签到系统 - 带失败重试版本")
    print("=" * 60)

    # 用户配置
    users = [
        {"user_id": "R8rdy6RWPnzj1YXm", "name": "用户A"},
        {"user_id": "o0rLk6oBKO4aA8QN", "name": "用户B"}
    ]

    results = []

    for user in users:
        user_id = user['user_id']
        name = user['name']

        print(f"\n{'=' * 50}")
        print(f" 处理用户: {name} ({user_id})")
        print(f"{'=' * 50}")

        # 创建签到系统实例
        sign_system = SSLSignSystem(user_id, config={
            'max_ads': 10,
            'ad_wait_time': 2,
            'request_timeout': 30,
            'retry_times': 3,
            'max_sign_attempts': 10,  # 最大签到尝试次数
            'sign_retry_delay': 60,  # 签到重试延迟(秒)
        })

        # 执行签到（带重试机制）
        result = sign_system.auto_sign_with_retry()
        result['name'] = name
        results.append(result)

        # 显示当前用户结果
        status = " 成功" if result.get('success') else " 失败"
        message = result.get('message', result.get('error', '未知'))

        if result.get('already_signed'):
            status = " 已签到"

        print(f"\n 用户 {name} 结果: {status}")
        print(f" 信息: {message}")
        if result.get('points_change'):
            print(f" 积分变化: +{result['points_change']}")
        print(f" 尝试次数: {result.get('attempts', 1)}")
        print(f" 本次耗时: {result.get('execution_time', 0)}秒")
        print(f" 总耗时: {result.get('total_time', 0)}秒")

        # 间隔3秒，避免请求过于频繁
        if user != users[-1]:  # 不是最后一个用户
            print("\n 等待3秒后处理下一个用户...")
            time.sleep(3)

    # 汇总结果
    print(f"\n{'=' * 60}")
    print(" 签到结果汇总")
    print(f"{'=' * 60}")

    success_count = sum(1 for r in results if r.get('success'))
    total_count = len(results)

    print(f"总计: {total_count} 个用户")
    print(f"成功: {success_count} 个")
    print(f"失败: {total_count - success_count} 个")
    print()

    for result in results:
        if result.get('already_signed'):
            status = " 已签到"
        else:
            status = " 成功" if result.get('success') else " 失败"
        message = result.get('message', result.get('error', '未知'))

        points_info = ""
        if result.get('points_change'):
            points_info = f" (+{result['points_change']}积分)"

        attempts_info = f" [尝试{result.get('attempts', 1)}次]"

        print(f"   {result['name']}: {status} - {message}{points_info}{attempts_info}")

    print(f"\n{'=' * 60}")
    print(" 自动签到任务执行完成!")
    print(f"{'=' * 60}")


if __name__ == "__main__":
    main()